<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>User Interface Signature</title>
<link rel="stylesheet" href="../../boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
<link rel="home" href="../../index.html" title="Chapter 1. Boost.Convert 2.0">
<link rel="up" href="../design_notes.html" title="Design Notes">
<link rel="prev" href="converter_signature.html" title="Converter Signature">
<link rel="next" href="../supporting_tools.html" title="Supporting Tools">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<div class="spirit-nav">
<a accesskey="p" href="converter_signature.html"><img src="../../images/prev.png" alt="Prev"></a><a accesskey="u" href="../design_notes.html"><img src="../../images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../images/home.png" alt="Home"></a><a accesskey="n" href="../supporting_tools.html"><img src="../../images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="boost_convert.design_notes.user_interface_signature"></a><a class="link" href="user_interface_signature.html" title="User Interface Signature">User
      Interface Signature</a>
</h3></div></div></div>
<p>
        The first attempt to accommodate the User Requirements might result in the
        following fairly conventional interface:
      </p>
<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">Out</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">In</span><span class="special">&gt;</span> <span class="identifier">Out</span>  <span class="identifier">convert</span> <span class="special">(</span><span class="identifier">In</span> <span class="keyword">const</span><span class="special">&amp;);</span> <span class="comment">//#1</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">Out</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">In</span><span class="special">&gt;</span> <span class="identifier">Out</span>  <span class="identifier">convert</span> <span class="special">(</span><span class="identifier">In</span> <span class="keyword">const</span><span class="special">&amp;,</span> <span class="identifier">Out</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">fallback</span><span class="special">);</span> <span class="comment">//#2</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">Out</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">In</span><span class="special">&gt;</span> <span class="keyword">bool</span> <span class="identifier">convert</span> <span class="special">(</span><span class="identifier">Out</span><span class="special">&amp;</span> <span class="identifier">result_out</span><span class="special">,</span> <span class="identifier">In</span> <span class="keyword">const</span><span class="special">&amp;);</span> <span class="comment">//#3</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">Out</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">In</span><span class="special">&gt;</span> <span class="keyword">bool</span> <span class="identifier">convert</span> <span class="special">(</span><span class="identifier">Out</span><span class="special">&amp;</span> <span class="identifier">result_out</span><span class="special">,</span> <span class="identifier">In</span> <span class="keyword">const</span><span class="special">&amp;,</span> <span class="identifier">Out</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">fallback</span><span class="special">);</span> <span class="comment">//#4</span>
</pre>
<p>
        with the following behavior:
      </p>
<div class="orderedlist"><ol class="orderedlist" type="1">
<li class="listitem">
            returns the result or throws on failure (<span class="emphasis"><em>R3a</em></span>, <span class="emphasis"><em>R4</em></span>);
          </li>
<li class="listitem">
            does not throw, returns the result or the provided fallback (<span class="emphasis"><em>R3b</em></span>,
            <span class="emphasis"><em>R5</em></span>, <span class="emphasis"><em>R5c</em></span> but not <span class="emphasis"><em>R5a</em></span>);
          </li>
<li class="listitem">
            does not throw, writes the result to <code class="computeroutput"><span class="identifier">result_out</span></code>
            (when successful), returns indication of success or failure (<span class="emphasis"><em>R3b</em></span>,
            <span class="emphasis"><em>R5</em></span>, <span class="emphasis"><em>R5a</em></span> but not <span class="emphasis"><em>R5c</em></span>);
          </li>
<li class="listitem">
            does not throw, writes the result to <code class="computeroutput"><span class="identifier">result_out</span></code>
            (when successful) or the provided fallback, returns indication of success
            or failure (<span class="emphasis"><em>R3b</em></span>, <span class="emphasis"><em>R5</em></span>, <span class="emphasis"><em>R5c</em></span>
            and <span class="emphasis"><em>R5a</em></span>).
          </li>
</ol></div>
<p>
        The #3 and #4 signatures are special as they, in fact, return two things
        -- the actual result (written into the <code class="computeroutput"><span class="identifier">result_out</span></code>)
        and the indication of success or failure (returned by the functions). Given
        that a reference to <code class="computeroutput"><span class="identifier">result_out</span></code>
        is passed in, the actual <code class="computeroutput"><span class="identifier">result_out</span></code>
        instance is constructed (storage allocated and initialized) outside the function
        calls.
      </p>
<p>
        Similar to the scenario described in the <a class="link" href="converter_signature.html" title="Converter Signature">Converter
        Signature</a> section that results in an additional and unnecessary overhead.
        Indeed, if the conversion operation succeeds, then the initialization value
        is overridden (with the actual result), if it fails, then the value is either
        overridden still (with the fallback) or is meaningless.
      </p>
<p>
        To avoid the overhead we might again (as in the <a class="link" href="converter_signature.html" title="Converter Signature">Converter
        Signature</a> section) deploy <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">optional</span></code>
        and to change the signatures to
      </p>
<pre class="programlisting"><span class="keyword">bool</span> <span class="identifier">convert</span> <span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">Out</span><span class="special">&gt;&amp;,</span> <span class="identifier">In</span> <span class="keyword">const</span><span class="special">&amp;);</span> <span class="comment">//#3</span>
<span class="keyword">bool</span> <span class="identifier">convert</span> <span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">Out</span><span class="special">&gt;&amp;,</span> <span class="identifier">In</span> <span class="keyword">const</span><span class="special">&amp;,</span> <span class="identifier">Out</span> <span class="keyword">const</span><span class="special">&amp;);</span> <span class="comment">//#4</span>
</pre>
<p>
        Now, when we look at #3, we can see that the indication of success or failure
        is duplicated. Namely, it is returned from the function and is encapsulated
        in <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">Out</span><span class="special">&gt;</span></code>.
        Consequently, #3 can be further simplified to
      </p>
<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">convert</span> <span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">Out</span><span class="special">&gt;&amp;,</span> <span class="identifier">In</span> <span class="keyword">const</span><span class="special">&amp;);</span> <span class="comment">//#3</span>
</pre>
<p>
        or expressed more idiomatically (in C++) as:
      </p>
<pre class="programlisting"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">Out</span><span class="special">&gt;</span> <span class="identifier">convert</span> <span class="special">(</span><span class="identifier">In</span> <span class="keyword">const</span><span class="special">&amp;);</span> <span class="comment">//#3</span>
</pre>
<p>
        So far, we have arrived to the following set
      </p>
<pre class="programlisting"><span class="identifier">Out</span>                  <span class="identifier">convert</span> <span class="special">(</span><span class="identifier">In</span> <span class="keyword">const</span><span class="special">&amp;);</span> <span class="comment">//#1</span>
<span class="identifier">Out</span>                  <span class="identifier">convert</span> <span class="special">(</span><span class="identifier">In</span> <span class="keyword">const</span><span class="special">&amp;,</span> <span class="identifier">Out</span> <span class="keyword">const</span><span class="special">&amp;);</span> <span class="comment">//#2</span>
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">Out</span><span class="special">&gt;</span> <span class="identifier">convert</span> <span class="special">(</span><span class="identifier">In</span> <span class="keyword">const</span><span class="special">&amp;);</span> <span class="comment">//#3</span>
<span class="keyword">bool</span>                 <span class="identifier">convert</span> <span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">Out</span><span class="special">&gt;&amp;,</span> <span class="identifier">In</span> <span class="keyword">const</span><span class="special">&amp;,</span> <span class="identifier">Out</span> <span class="keyword">const</span><span class="special">&amp;);</span> <span class="comment">//#4</span>
</pre>
<p>
        which as a whole looks quite ugly and, in fact, does not even compile as
        #1 clashes with #3. The good thing though is that <span class="emphasis"><em>functionally</em></span>
        #1 and #2 are not needed anymore as they are duplicates of the following
        #3 deployments:
      </p>
<pre class="programlisting"><span class="identifier">Out</span> <span class="identifier">out1</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">convert</span><span class="special">(</span><span class="identifier">in</span><span class="special">).</span><span class="identifier">value</span><span class="special">();</span> <span class="comment">// #3 with #1 behavior</span>
<span class="identifier">Out</span> <span class="identifier">out2</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">convert</span><span class="special">(</span><span class="identifier">in</span><span class="special">).</span><span class="identifier">value_or</span><span class="special">(</span><span class="identifier">fallback</span><span class="special">);</span> <span class="comment">// #3 with #2 behavior</span>
</pre>
<p>
        Again, we are not discussing aesthetic aspects of the interface (or syntactic
        sugar some might say, which might be very subjective). Instead, we are focusing
        on the <span class="emphasis"><em>functional completeness</em></span> and so far we manage
        to maintain the same <span class="emphasis"><em>functional completeness</em></span> with <span class="emphasis"><em>less</em></span>.
      </p>
<p>
        Turns out, with a bit of effort, we can get away without the most complex
        one -- #4 -- as well:
      </p>
<pre class="programlisting"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">Out</span><span class="special">&gt;</span> <span class="identifier">out</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">convert</span><span class="special">(</span><span class="identifier">in</span><span class="special">);</span>
<span class="keyword">bool</span>         <span class="identifier">out_success</span> <span class="special">=</span> <span class="identifier">out</span> <span class="special">?</span> <span class="keyword">true</span> <span class="special">:</span> <span class="keyword">false</span><span class="special">;</span>
<span class="identifier">Out</span>            <span class="identifier">out_value</span> <span class="special">=</span> <span class="identifier">out</span><span class="special">.</span><span class="identifier">value_or</span><span class="special">(</span><span class="identifier">fallback</span><span class="special">);</span>
</pre>
<p>
        So, ultimately we arrive to one and only
      </p>
<pre class="programlisting"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">Out</span><span class="special">&gt;</span> <span class="identifier">convert</span><span class="special">(</span><span class="identifier">In</span> <span class="keyword">const</span><span class="special">&amp;);</span>
</pre>
<p>
        The important qualities of the API are that it is <span class="emphasis"><em>functionally-complete</em></span>
        and the <span class="emphasis"><em>most efficient way</em></span> to deploy the chosen converter
        signature (see the <a class="link" href="converter_signature.html" title="Converter Signature">Converter
        Signature</a> section). Namely, the <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">convert</span><span class="special">()</span></code> interface is routinely optimized out (elided)
        when deployed as
      </p>
<pre class="programlisting"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">Out</span><span class="special">&gt;</span> <span class="identifier">out</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">convert</span><span class="special">(</span><span class="identifier">in</span><span class="special">);</span>
</pre>
<p>
        The API has several deployment-related advantages. First, it says exactly
        what it does. Given a conversion request is only a <span class="emphasis"><em>request</em></span>,
        the API returns <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">optional</span></code> essentially saying "I'll
        try but I might fail. Proceed as you find appropriate.". Honest and
        simple. I prefer it to "I'll try. I might fail but you do not want to
        know about it." or "I'll try. If I fail, you die." or variations
        along these lines. :-)
      </p>
<p>
        On a more serious note though the interface allows for batched conveyor-style
        conversions. Namely, attempting to convert several values, in sequence, storing
        the <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">optional</span></code> results and, then, analyzing/validating
        them (without losing the information if each individual conversion was successful
        or not) in some semi-automated way.
      </p>
<p>
        Again, that API does not have to be the only API <span class="emphasis"><em>Boost.Convert</em></span>
        provides. However, that API is the only <span class="emphasis"><em>essential</em></span> API.
        Other APIs are relatively easily derived from it. For example,
      </p>
<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">Out</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">In</span><span class="special">&gt;</span>
<span class="identifier">Out</span>
<span class="identifier">convert</span><span class="special">(</span><span class="identifier">In</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">in</span><span class="special">,</span> <span class="identifier">Out</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">fallback</span><span class="special">)</span> <span class="comment">//#2</span>
<span class="special">{</span>
   <span class="keyword">return</span> <span class="identifier">convert</span><span class="special">(</span><span class="identifier">in</span><span class="special">).</span><span class="identifier">value_or</span><span class="special">(</span><span class="identifier">fallback</span><span class="special">);</span>
<span class="special">}</span>
</pre>
<p>
        Given that it is extremely difficult (if not impossible) to come up with
        a library API that could please everyone, we might as well settle on the
        <span class="emphasis"><em>essential</em></span> API and let the users build their own APIs
        (as in the example above) to satisfy their aesthetic preferences.
      </p>
<p>
        Still, it needs to be acknowledged that <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">optional</span></code>
        is a fairly new concept and some people are reluctant using it or find its
        deployment unreasonably complicating. Consequently, <span class="emphasis"><em>Boost.Convert</em></span>
        provides an alternative (more conventional) interface:
      </p>
<pre class="programlisting"><span class="identifier">Out</span> <span class="identifier">convert</span><span class="special">(</span><span class="identifier">In</span> <span class="keyword">const</span><span class="special">&amp;,</span> <span class="identifier">Converter</span> <span class="keyword">const</span><span class="special">&amp;,</span> <span class="identifier">Out</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">fallback_value</span><span class="special">);</span>
<span class="identifier">Out</span> <span class="identifier">convert</span><span class="special">(</span><span class="identifier">In</span> <span class="keyword">const</span><span class="special">&amp;,</span> <span class="identifier">Converter</span> <span class="keyword">const</span><span class="special">&amp;,</span> <span class="identifier">Functor</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">fallback_functor</span><span class="special">);</span>
<span class="identifier">Out</span> <span class="identifier">convert</span><span class="special">(</span><span class="identifier">In</span> <span class="keyword">const</span><span class="special">&amp;,</span> <span class="identifier">Converter</span> <span class="keyword">const</span><span class="special">&amp;,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">throw_on_failure</span><span class="special">);</span>
</pre>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><div class="copyright-footer">Copyright © 2009-2022 Vladimir
      Batov<p>
        Distributed under the Boost Software License, Version 1.0. See copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>.
      </p>
</div></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="converter_signature.html"><img src="../../images/prev.png" alt="Prev"></a><a accesskey="u" href="../design_notes.html"><img src="../../images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../images/home.png" alt="Home"></a><a accesskey="n" href="../supporting_tools.html"><img src="../../images/next.png" alt="Next"></a>
</div>
</body>
</html>
